#include "Thread.hpp"
#include "lockGuard.hpp"
#include <iostream>
#include <unistd.h>
#include <pthread.h>

using namespace std;

// Task： encapsulation mutex and thread --> 对锁和线程加点设计，对他们进行封装
int tickets = 5000;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 线程的入口函数
void *threadRoutine(void *args)
{
    Thread *td = static_cast<Thread *>(args); // 将类型安全转换
    while (true)
    {
        // pthread_mutex_lock(&mutex);  //这样加锁不太美观
        {
            //RAII风格加锁 --> 使用随生命周期
            //手动{} 加锁，也表明了这个是临界区
            //外界去维护mutex，这个组件，就是对锁进行加锁和解锁的使用，
            //让它自动化，可以随生命周期而自动加锁，解锁
            LockGuard lockguard(&mutex);
            if (tickets > 0)
            {
                usleep(1000); // 抢票相关操作
                cout << td->getName() << " get a ticket " << tickets-- << endl;
                // pthread_mutex_unlock(&mutex);
            }
            else
            {
                // pthread_mutex_unlock(&mutex);
                break;
            }
            
        }
        // pthread_mutex_unlock(&mutex); //error,放在这里是不对的，因为如果直接break的话，锁就没有被释放
        usleep(500); // 抢到票后的相关操作
    }
    return nullptr;
}

int main()
{
    Thread t1(1, threadRoutine, &t1);
    Thread t2(1, threadRoutine, &t2);
    Thread t3(1, threadRoutine, &t3);
    Thread t4(1, threadRoutine, &t4);

    t1.run();
    t2.run();
    t3.run();
    t4.run();

    t1.join();
    t2.join();
    t3.join();
    t4.join();

    return 0;
}
